import type { TreeNodeNormal } from "antd/es/tree/Tree";

export enum ToolbarEnum {
	SELECT_ALL,
	UN_SELECT_ALL,
	EXPAND_ALL,
	UN_EXPAND_ALL,
	CHECK_STRICTLY,
	CHECK_UN_STRICTLY
}

export const treeEmits = ["update:expandedKeys", "update:selectedKeys", "update:value", "change", "check", "update:searchValue"];

export interface TreeState {
	expandedKeys: KeyType[];
	selectedKeys: KeyType[];
	checkedKeys: CheckKeys;
	checkStrictly: boolean;
}

export interface FieldNames {
	children?: string;
	title?: string;
	key?: string;
}

export type KeyType = string | number;

export type CheckKeys = KeyType[] | { checked: string[] | number[]; halfChecked: string[] | number[] };

export const treeProps = {
	value: {
		type: [Object, Array] as PropType<KeyType[] | CheckKeys>
	},

	renderIcon: {
		type: Function as PropType<(...params: any[]) => string>
	},

	helpMessage: {
		type: [String, Array] as PropType<string | string[]>,
		default: ""
	},

	title: {
		type: String,
		default: ""
	},
	toolbar: Boolean,
	search: Boolean,
	searchValue: {
		type: String,
		default: ""
	},
	checkStrictly: Boolean,
	clickRowToExpand: {
		type: Boolean,
		default: false
	},
	checkable: Boolean,
	defaultExpandLevel: {
		type: [String, Number] as PropType<string | number>,
		default: ""
	},
	defaultExpandAll: Boolean,
	// 是否显示toolbar的 层级关联/层级独立按钮
	showStrictlyButton: {
		type: Boolean,
		default: true
	},

	fieldNames: {
		type: Object as PropType<FieldNames>
	},

	treeData: {
		type: Array as PropType<TreeNodeNormal[]>
	},

	actionList: {
		type: Array as PropType<TreeActionItem[]>,
		default: () => []
	},

	expandedKeys: {
		type: Array as PropType<KeyType[]>
	},

	selectedKeys: {
		type: Array as PropType<KeyType[]>,
		default: () => []
	},

	checkedKeys: {
		type: [Array, Object] as PropType<CheckKeys>,
		default: () => []
	},

	beforeRightClick: {
		type: Function as PropType<(...arg: any) => ContextMenuItem[] | ContextMenuOptions>,
		default: undefined
	},

	rightMenuList: {
		type: Array as PropType<ContextMenuItem[]>
	},
	// 自定义数据过滤判断方法(注: 不是整个过滤方法，而是内置过滤的判断方法，用于增强原本仅能通过title进行过滤的方式)
	filterFn: {
		type: Function as PropType<(searchValue: any, node: TreeItem, fieldNames: FieldNames) => boolean>,
		default: undefined
	},
	// 高亮搜索值，仅高亮具体匹配值（通过title）值为true时使用默认色值，值为#xxx时使用此值替代且高亮开启
	highlight: {
		type: [Boolean, String] as PropType<boolean | string>,
		default: false
	},
	// 搜索完成时自动展开结果
	expandOnSearch: Boolean,
	// 搜索完成自动选中所有结果,当且仅当 checkable===true 时生效
	checkOnSearch: Boolean,
	// 搜索完成自动select所有结果
	selectedOnSearch: Boolean,
	loading: {
		type: Boolean,
		default: false
	},
	treeWrapperClassName: String
};

export type TreeProps = typeof treeProps;

export interface ContextMenuItem {
	label: string;
	icon?: string;
	hidden?: boolean;
	disabled?: boolean;
	handler?: Fn;
	divider?: boolean;
	children?: ContextMenuItem[];
}

export interface ContextMenuOptions {
	icon?: string;
	styles?: any;
	items?: ContextMenuItem[];
}

export interface TreeItem extends TreeNodeNormal {
	icon?: any;
}

export interface TreeActionItem {
	render: (record: Recordable) => any;
	show?: boolean | ((record: Recordable) => boolean);
}

export interface InsertNodeParams {
	parentKey: string | null;
	node?: TreeNodeNormal;
	list?: TreeNodeNormal[];
	push?: "push" | "unshift";
}

export interface TreeActionType {
	getTreeData: () => TreeNodeNormal[];
	checkAll: (checkAll: boolean) => void;
	expandAll: (expandAll: boolean) => void;
	setExpandedKeys: (keys: KeyType[]) => void;
	getExpandedKeys: () => KeyType[];
	setSelectedKeys: (keys: KeyType[]) => void;
	getSelectedKeys: () => KeyType[];
	setCheckedKeys: (keys: CheckKeys) => void;
	getCheckedKeys: () => CheckKeys;
	filterByLevel: (level: number) => void;
	insertNodeByKey: (opt: InsertNodeParams) => void;
	insertNodesByKey: (opt: InsertNodeParams) => void;
	deleteNodeByKey: (key: string, list?: TreeNodeNormal[]) => void;
	updateNodeByKey: (key: string, node: Omit<TreeNodeNormal, "key">) => void;
	setSearchValue: (value: string) => void;
	getSearchValue: () => string;
	getSelectedNode: (key: KeyType, treeList?: TreeItem[], selectNode?: TreeItem | null) => TreeItem | null;
}

export interface CheckedEvent<T = any> {
	checked: boolean; // 是否选中节点 一个没选为false
	checkedNodes: T[]; // 选中的节点 类型为treeData的类型
	checkedNodesPositions?: any; // 选中节点的位置 eg:0-0-1 节点独立时候为null
	event: "check";
	halfCheckedKeys?: number[]; // 父子节点关联时为祖先节点ids, 独立时为null
	nativeEvent: PointerEvent;
	node: any;
}

/**
 * 父子节点关联情况下
 * 为选中的菜单id(包含子菜单 不包含父菜单)
 *
 * 父子节点独立情况下
 * checked为选中的菜单
 * halfChecked为祖先节点数组
 */
export type CheckedKeys =
	| number[]
	| {
			checked: number[];
			halfChecked: number[];
	  };
